﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using CommonWFLibrary;
using IndicoInterface.SimpleAgendaDataModel;
using System.Collections.Generic;
using System.IO;
using DTBuilderLib;

namespace DeepTalkWF
{
    /// <summary>
    /// Render a meeting to jpeg images
    /// </summary>
	public partial class RenderAllMeetingSlides: LongRunningActivityBase
	{
        /// <summary>
        /// Render a meeting in the background. Can take a long time!!!
        /// </summary>
		public RenderAllMeetingSlides()
		{
			InitializeComponent();
            TimesToRetry = 10;
		}

        /// <summary>
        /// Pointers to the list of talks
        /// </summary>
        public Meeting MeetingInfo
        {
            get { return (Meeting)GetValue(MeetingInfoProperty); }
            set { SetValue(MeetingInfoProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MeetingInfo.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MeetingInfoProperty =
            DependencyProperty.Register("MeetingInfo", typeof(Meeting), typeof(RenderAllMeetingSlides), new PropertyMetadata(null));

        /// <summary>
        /// The DPI the should be rendering at.
        /// </summary>
        public int DPI
        {
            get { return (int)GetValue(DPIProperty); }
            set { SetValue(DPIProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DPI.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DPIProperty =
            DependencyProperty.Register("DPI", typeof(int), typeof(RenderAllMeetingSlides), new PropertyMetadata(300));

        /// <summary>
        /// Returns the rendered talks for this guy
        /// </summary>
        public Dictionary<Talk,List<FileInfo>> RenderedTalks
        {
            get { return (Dictionary<Talk,List<FileInfo>>)GetValue(RenderedTalksProperty); }
            set { SetValue(RenderedTalksProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RenderedTalks.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RenderedTalksProperty =
            DependencyProperty.Register("RenderedTalks", typeof(Dictionary<Talk,List<FileInfo>>), typeof(RenderAllMeetingSlides), new PropertyMetadata(null));

        /// <summary>
        /// Output -- how many slides were rendered.
        /// </summary>
        public int NumberOfRenderedTalks
        {
            get { return (int)GetValue(NumberOfRenderedTalksProperty); }
            set { SetValue(NumberOfRenderedTalksProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NumberOfRenderedTalks.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NumberOfRenderedTalksProperty =
            DependencyProperty.Register("NumberOfRenderedTalks", typeof(int), typeof(RenderAllMeetingSlides), new PropertyMetadata(0));


        /// <summary>
        /// Internal class to pass arguments to the long running task
        /// </summary>
        [Serializable]
        public class Args
        {
            public int _dpi;
            public Meeting _m;
        }

        [LongRunningGatherArguments]
        public Args Gather ()
        {
            Args a = new Args();
            a._dpi = DPI;
            a._m = MeetingInfo;
            return a;
        }

        [Serializable]
        public class Results
        {
            public Dictionary<Talk, List<FileInfo>> _talks;
            public int _count;
        }

        [LongRunningDistributeArguments]
        public void Distribute(Results r)
        {
            RenderedTalks = r._talks;
            NumberOfRenderedTalks = r._count;
        }

        /// <summary>
        /// Render the meeting - we are currently living in a seperate thread for this...
        /// </summary>
        /// <param name="a"></param>
        /// <returns></returns>
        [LongRunningMethod]
        public static Results Run(Args a)
        {
            Results r = new Results();

            JPEGRender rj = new JPEGRender();
            rj.DotsPerInch = a._dpi;

            r._talks = rj.RenderMeeting(a._m);

            /// COunt number of talks with non-zero numbers of slides!
            r._count = (from t in r._talks where t.Value.Count > 0 select t.Key).Count();

            return r;
        }
	}
}
